﻿//////////////////////////////////////////////////
//                  Archer.cs                   //
//         Part of RebornCo by kaihaider        //
//////////////////////////////////////////////////

using System.Linq;
using System.Threading.Tasks;
using ff14bot;
using ff14bot.Enums;
using ff14bot.Objects;
using RebornCo.Settings;
using RebornCo.Helpers;
using TreeSharp;

namespace RebornCo.Rotations
{
    public class Archer : RebornCoRoutine
    {
        public override void OnInitialize()
        {
            WantHealing = false;
            WindowSettings = new ArcherSetting();
        }
        public static ArcherSetting Settings
        {
            get { return WindowSettings as ArcherSetting; }
        }
        public sealed override ClassJobType[] Class
        {
            get
            {
                return new [] 
                { 
                   ClassJobType.Archer, ClassJobType.Bard
                };
            }
        }
        [Behavior(BehaviorType.PreCombatBuffs)]
        public Composite ArcherCreateBasicPreCombatBuffs()
        {
            return new ActionRunCoroutine(ctx => ArcherBuildPreCombatBuffs());
        }
        public static async Task<bool> ArcherBuildPreCombatBuffs()
        {
            if (!IsValid()) return false;
            if (Resting)
            {
                if (!Core.Player.IsCasting && await Spell.Cast("Cure", Core.Player, Core.Player.CurrentHealthPercent < 70 && Core.Player.CurrentHealthPercent < Core.Player.CurrentManaPercent)) return true;
                if (!Core.Player.IsCasting && await Spell.Cast("Physick", Core.Player, Core.Player.CurrentHealthPercent < 70 && Core.Player.CurrentHealthPercent < Core.Player.CurrentManaPercent)) return true;
                return false;
            }
            //setting for Swiftsong
            if (await Spell.BuffParty("Protect")) return true;
            if (await Spell.BuffParty("Stoneskin")) return true;
            return await CombatCompanion();
        }

        [Behavior(BehaviorType.Rest)]
        public Composite ArcherCreateBasicRest()
        {
            return new ActionRunCoroutine(ctx => DefaultRestBehavior(Core.Player.CurrentTPPercent)); 
        }


        [Behavior(BehaviorType.CombatBuffs)]
        public Composite ArcherCreateBasicCombatBuffs()
        {
            return new ActionRunCoroutine(ctx => ArcherBuildCombatBuffs()); 
        }
        public static async Task<bool> ArcherBuildCombatBuffs()
        {
            //shadow bind adds
            //Repelling Shot kite
            ShouldPulse = true;
            if (await Spell.Cast("Cure", Core.Player, Core.Player.CurrentHealthPercent < 40)) return true;
            if (await Spell.Cast("Physick", Core.Player, Core.Player.CurrentHealthPercent < 40)) return true;
            if (Spell.GcdTime < Settings.NoneGcdWindowEnd) return false;
            if (!Spell.UsedNoneGcd && (Settings.MagesBallad || Settings.FoeRequiem || Settings.ArmysPaeon)
                && Core.Player.CurrentManaPercent > Settings.ManaForSongs+5 && ff14bot.Managers.PartyManager.IsInParty)
                await ScanParty();
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Bloodletter", Core.Player.CurrentTarget))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.Cast("Misery's End", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent < 20))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Blood for Blood", Core.Player, Core.Player.ClassLevel < 26 || Spell.GetSpellData("Hawk's Eye").Cooldown.TotalSeconds < 5))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Hawk's Eye", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Raging Strikes", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Internal Release", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (Settings.CooldownsUsable && Spell.Potion != null && Spell.Potion.IsValid
                && Spell.Potion.CanUse(Core.Player) && Spell.Potion.Name.Equals(Settings.PotionName))
            {
                Spell.Potion.UseItem(Core.Player);
                if (Settings.PotionForce) Spell.UsedNoneGcd = true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Barrage", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Quelling Strikes", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Invigorate", Core.Player, Core.Player.CurrentTPPercent < 50))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Eye for an Eye", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Foresight", Core.Player, Core.Player.CurrentHealthPercent < 80))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Bloodbath", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Keen Flurry", Core.Player, Core.Player.CurrentHealthPercent < 80))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Convalescence", Core.Player, Core.Player.CurrentHealthPercent < 70))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Second Wind", Core.Player, Core.Player.CurrentHealthPercent < 40))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Awareness", Core.Player, Core.Player.CurrentHealthPercent < 30))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Featherfoot", Core.Player, Core.Player.Distance2D() < 5))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            return false;
        }


        [Behavior(BehaviorType.Pull)]
        public Composite ArcherCreateBasicPull()
        {
            return new ActionRunCoroutine(ctx => ArcherBuildPullBehavior()); 
        }
        public static async Task<bool> ArcherBuildPullBehavior()
        {
            if (Core.Player.CurrentTarget != null && !Core.Player.CurrentTarget.CanAttack || !IsValid()) return false;
            ShouldPulse = true;
            await Target.EnsureValidTarget();
            if (await Movement.PullMove(Core.Player.CurrentTarget)) return true;

            if (await Spell.CastLock("Quelling Strikes", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }

            if (await Spell.PullCast("Windbite", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent > Settings.MinDotHp
                        && !Core.Player.CurrentTarget.HasAura("Windbite", true, Settings.WindbiteClip))) return true;
            if (await Spell.PullCast("Venomous Bite", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent > Settings.MinDotHp
                        && !Core.Player.CurrentTarget.HasAura("Venomous Bite", true, Settings.VenomousClip))) return true;
            if (await Spell.PullCast("Straight Shot", Core.Player.CurrentTarget, !Core.Player.HasAura("Straight Shot"))) return true;

            if (await Spell.PullCast("Heavy Shot", Core.Player.CurrentTarget)) return true;
            return false;
        }

        [Behavior(BehaviorType.Combat)]
        public Composite ArcherCreateBasicCombat()
        {
            return new ActionRunCoroutine(ctx => ArcherBuildBasicCombat()); 
        }
        public static async Task<bool> ArcherBuildBasicCombat()
        {
            await Target.EnsureValidTarget();
            await Movement.MoveToTarget();
            if (Core.Player.CurrentTarget != null && ff14bot.Managers.MovementManager.IsMoving
                && !(Core.Player.CurrentTarget.InLineOfSight() && Movement.IsInSafeRange(Core.Player.CurrentTarget))) return true;
            //Quick Nock 8 yard frontal cone
            //Wide Volley 5 yards from target
            //Raid of Death 8 yards from target

            if (!Spell.Gcd && Settings.MagesBallad && LowMana >= Settings.SongManaCount &&
                await Spell.CastLock("Mage's Ballad", Core.Player, !Core.Player.HasAura("Mage's Ballad"))) return true;
            if (!Spell.Gcd && Settings.FoeRequiem && LowHp >= Settings.SongHpCount &&
                await Spell.CastLock("Foe Requiem", Core.Player, !Core.Player.HasAura("Foe Requiem"))) return true;
            if (!Spell.Gcd && Settings.ArmysPaeon && LowTp >= Settings.SongTpCount &&
                await Spell.CastLock("Army's Paeon", Core.Player, !Core.Player.HasAura("Army's Paeon"))) return true;
            if (Settings.MagesBallad && (Core.Player.CurrentManaPercent < Settings.ManaForSongs || LowMana < Settings.SongManaCount)
                && await Spell.CastLock("Mage's Ballad", Core.Player, Core.Player.HasAura("Mage's Ballad")))
            if (Settings.FoeRequiem && (Core.Player.CurrentManaPercent < Settings.ManaForSongs || LowHp < Settings.SongHpCount)
                && await Spell.CastLock("Foe Requiem", Core.Player, Core.Player.HasAura("Foe Requiem")))
            if (Settings.ArmysPaeon && (Core.Player.CurrentManaPercent < Settings.ManaForSongs || LowTp < Settings.SongTpCount)
                && await Spell.CastLock("Army's Paeon", Core.Player, Core.Player.HasAura("Army's Paeon")))

            if (!Spell.Gcd && await Spell.CastLock("Venomous Bite", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent > Settings.MinDotHp
                        && !Core.Player.CurrentTarget.HasAura("Venomous Bite", true, Settings.VenomousClip))) return true;
            if (!Spell.Gcd && await Spell.CastLock("Windbite", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent > Settings.MinDotHp
                        && !Core.Player.CurrentTarget.HasAura("Windbite", true,Settings.WindbiteClip))) return true;

            if (!Spell.Gcd && await Spell.CastLocation("Flaming Arrow", Core.Player.CurrentTarget, true)) return true;

            if (!Spell.Gcd && await Spell.CastLock("Straight Shot", Core.Player.CurrentTarget, !Core.Player.HasAura("Straight Shot") || Core.Player.HasAura("Straighter Shot"))) return true;

            if (!Spell.Gcd && await Spell.Cast("Heavy Shot", Core.Player.CurrentTarget)) return true;

            if (Spell.GcdTime < Settings.NoneGcdWindowEnd) return false;
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Mercy Stroke", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent < 20))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Blunt Arrow", Core.Player.CurrentTarget))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Battle Voice", Core.Player, Settings.BattleVoice && (Core.Player.HasAura("Mage's Ballad") || Core.Player.HasAura("Foe Requiem") || Core.Player.HasAura("Army's Paeon"))))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            return false;
        }

        public static byte LowTp, LowMana, LowHp;

#pragma warning disable 1998
        public static async Task ScanParty()
#pragma warning restore 1998
        {
            LowTp = 0;
            LowMana = 0;
            LowHp = 0;
            foreach (var p in ff14bot.Managers.PartyManager.VisibleMembers.Where(p => p != null && p.IsValid && p.IsInObjectManager && (p.GameObject as Character) != null && p.GameObject.Distance2D() < 20))
            {
                if (((Character) p.GameObject).CurrentTPPercent < Settings.SongTpPercent) LowTp++;
                if (((Character) p.GameObject).CurrentManaPercent < Settings.SongManaPercent) LowMana++;
                if (p.GameObject.CurrentHealthPercent < Settings.SongHpPercent) LowHp++;
            }
        }
    }
}
